#ifndef xpack_lang_cxx_find_reverse
#define xpack_lang_cxx_find_reverse
#pragma push_macro("xuser")
#undef  xuser
#define xuser mixc::lang_cxx::inc
#include"define/base_type.hpp"
#include"lang/cxx/find.hpp"
#include"lang/cxx/index_of_last.hpp"
#include"lang/cxx.hpp"
#pragma pop_macro("xuser")

namespace mixc::lang_cxx{
    inline uxx find_reverse_core(auto const & self, auto const & pattern_list, auto const & compare, auto const & when_match){
        auto pos    = cxx_position{};
        uxx  i_th   = 0;
        uxx  i      = self->length;

        while(i-- > 0){
            for(uxx j = 0, length = pattern_list->length; j < length; j++){
                // 约定:
                // left 为待匹配字符串的字符，right 为匹配参数字符
                if (compare(self[i], pattern_list[j]) != 0){
                    continue;
                }
                if (pos->i_th = i_th++,
                    pos->offset = i; 
                    when_match(pos) == loop_t::finish){
                    return i_th;
                }
                else{
                    break;
                }
            }
        }
        return i_th;
    }

    inline uxx find_reverse_n_core(auto const & self, auto const & pattern_list, ixx n_th, auto const & compare){
        if (n_th < 0){
            return self.find(pattern_list, -n_th - 1, compare);
        }

        uxx i_th    = 0;
        uxx i       = self->length;

        while(i-- > 0){
            for(uxx j = 0, length = pattern_list->length; j < length; j++){
                // 约定:
                // left 为待匹配字符串的字符，right 为匹配参数字符
                if (compare(self[i], pattern_list[j]) != 0){
                    continue;
                }
                if (i_th++ == uxx(n_th)){
                    return i;
                }
            }
        }

        return not_exist;
    }
    

    #define xheaderx                            \
        template<class item_t>                  \
        template<class item_seq_t, class>       \
        inline uxx cxx<item_t>

    xheaderx::find_reverse(item_seq_t const & pattern_list, invoke_find_t when_match) const {
        return xthe.find_reverse(pattern_list, inc::default_compare<item_t>, when_match);
    }

    xheaderx::find_reverse(item_seq_t const & pattern_list, invoke_compare_t compare, invoke_find_t when_match) const {
        auto list = inc::unified_seq<item_seq_t>(pattern_list);
        return find_reverse_core(xthe, list, compare, when_match);
    }

    xheaderx::find_reverse(item_seq_t const & pattern_list, ixx n_th, invoke_compare_t compare) const {
        auto list = inc::unified_seq<item_seq_t>(pattern_list);
        return find_reverse_n_core(xthe, list, n_th, compare);
    }

    template<class item_t>
    inline uxx cxx<item_t>::find_reverse(item_cref_t pattern, invoke_find_t when_match) const {
        return xthe.find_reverse({ pattern }, inc::default_compare<item_t>, when_match);
    }

    template<class item_t>
    inline uxx cxx<item_t>::find_reverse(item_cref_t pattern, invoke_compare_t compare, invoke_find_t when_match) const {
        return xthe.find_reverse({ pattern }, compare, when_match);
    }

    template<class item_t>
    inline uxx cxx<item_t>::find_reverse(item_cref_t pattern, ixx n_th, invoke_compare_t compare) const {
        return xthe.find_reverse({ pattern }, n_th, compare);
    }



    template<class item_t>
    inline uxx cxx<item_t>::find_reverse(the_cref_t pattern, invoke_find_t when_match) const {
        return xthe.find_reverse(pattern, inc::default_compare<item_t>, when_match);
    }

    template<class item_t>
    inline uxx cxx<item_t>::find_reverse(the_cref_t pattern, invoke_compare_t compare, invoke_find_t when_match) const {
        uxx     i_th        = 0;
        uxx     i           = 0;
        auto    pos         = cxx_position{};
        auto    cur         = xthe;

        for(;; cur->length = i){
            if (i = cur.index_of_last(pattern, compare); i == not_exist){
                break;
            }
            if (pos->i_th = i_th++,
                pos->offset = i; 
                when_match(pos) == loop_t::finish){
                break;
            }
        }
        return i_th;
    }

    template<class item_t>
    inline uxx cxx<item_t>::find_reverse(the_cref_t pattern, ixx n_th, invoke_compare_t compare) const {
        if (n_th < 0){
            return xthe.find(pattern, -n_th - 1, compare);
        }

        uxx     i_th        = 0;
        uxx     i           = 0;
        auto    cur         = xthe;

        for(;; cur->length = i){
            if (i = cur.index_of_last(pattern, compare); i == not_exist){
                break;
            }
            if (i_th++ == uxx(n_th)){
                return i;
            }
        }
        return not_exist;
    }

    #undef  xheaderx
}

#endif
